package uk.ac.aber.paws.client.power;

import uk.ac.aber.paws.client.core.*;
import static uk.ac.aber.paws.client.constants.Constants.*;
import static uk.ac.aber.paws.client.constants.DatabaseEntryConstants.*;
import uk.ac.aber.paws.client.db.DBLogger;
import uk.ac.aber.paws.client.state.LoginInfo;
import uk.ac.aber.paws.client.state.LoginProcessOperations;
import static uk.ac.aber.paws.client.constants.CommandConstants.*;
import java.sql.Timestamp;
import java.util.*;

/**
 * @author Rob Johnson, Aberystwyth University
 * @email rob.johnson@aber.ac.uk
 * @date 16th August 2011
 * 
 * SleepOperations.java
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class SleepOperations {
		
	/**
	 * This function is called when the server has initiated a sleep request on the client. The sleep 
	 * event is logged to the database and then sleeps the computer. If the client can't log to the database, then the 
	 * sleep process is terminated as not to affect the power management logging. 
	 */
	public static boolean initiateServerInitiatedSleep() {
		
		// perform a check with the wake detector to check that it hasn't just woke up and also
		// that a successfully login check has been made in the last minute
		if (WakeDetector.pleaseCanITryToSleep() && LoginProcessOperations.checkLastCheck() && !PAWSClient.SYSTEM_STATE.getLoginRegister().getProblemsDetected()) {
		
			if ((new DBLogger()).registerPowerEvent(PAWSClient.SYSTEM_STATE.getComputerInfo().getComputerName(),SLEEP_EVENT_SERVER,new Timestamp(Calendar.getInstance().getTimeInMillis()))) {
			
				sleepMe(-1l);
				return true;
			}
			else {
				System.out.println("SLEEP FAILED DUE TO FAILURE TO REPORT TO DATABASE");
			}
		}
		else {
			System.out.println("SLEEP FAILED DUE TO FAILURE TO REPORT TO DATABASE");
		}
		
		return false;
	}
	
	/**
	 * Performs the actual sleep process on the windows computer
	 * @param sleepInterval
	 */
	public static void sleepMe(long sleepInterval) {
		
		try {
			
			if (sleepInterval > -1l) {
			/*	
				// turn hibernate function off so that we ensure it enters a slight sleep
				Process p = Runtime.getRuntime().exec("cmd.exe /c powercfg -hibernate off");
				
				p.waitFor();
				
				// perform the sleep on the windows computer
				p = Runtime.getRuntime().exec("cmd.exe /c rundll32 powrprof.dll,SetSuspendState Sleep");
				
				Thread.sleep(60000l);
				
				PAWSClient.SYSTEM_STATE.resetLastUserLoginTimeFollowingSleepPeriod();
			*/
			}
			// server initiated sleep...
			else {
				
				String os = PAWSClient.SYSTEM_STATE.getComputerInfo().getOperatingSystem();
				
				if (os.equals(OS_FLAG_WINDOWSXP) || os.equals(OS_FLAG_WINDOWSVISTA) || os.equals(OS_FLAG_WINDOWS7)) {
				
					// store the time of this sleep event
					PAWSClient.SYSTEM_STATE.getPowerEventInfo().setLastSleep(Calendar.getInstance().getTimeInMillis());
					
					Process p = Runtime.getRuntime().exec(COMMAND_HIBERNATE_OFF);
					p.waitFor();
				
					if (os.equals(OS_FLAG_WINDOWSXP)) {
						p = Runtime.getRuntime().exec(COMMAND_SLEEP_COMPUTER_XP);
					}
					else if (os.equals(OS_FLAG_WINDOWS7) || os.equals(OS_FLAG_WINDOWSVISTA)) {
						p = Runtime.getRuntime().exec(COMMAND_SLEEP_COMPUTER_WIN);
					}
				}
				else if (os.equals(OS_FLAG_LINUX)) {
					
					// store the time of this sleep event
					PAWSClient.SYSTEM_STATE.getPowerEventInfo().setLastSleep(Calendar.getInstance().getTimeInMillis());
					
					Process p = Runtime.getRuntime().exec(LINUX_COMMAND_SLEEP_COMPUTER);
					p.waitFor();
				}
				else if (os.equals(OS_FLAG_MAC)) {
					
					// store the time of this sleep event
					PAWSClient.SYSTEM_STATE.getPowerEventInfo().setLastSleep(Calendar.getInstance().getTimeInMillis());
					
				
					Process p = Runtime.getRuntime().exec(MAC_COMMAND_SLEEP_COMPUTER);
					p.waitFor();
				}
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
}
